home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / PROLOG / BP330 / !BinPro330 / progs / semi3 < prev    next >
Text File  |  1994-02-25  |  6KB  |  200 lines

  1. go:-go('BMARK_semigroup:').
  2.  
  3. go(Mes):-go(T,N),write(Mes=[time(T),n(N)]),nl.
  4.  
  5.  
  6. /*-----------------------------------------------------------------------------
  7. Program:  Semigroup (hash 2--3 tree version)
  8. Author:   R. Overbeek
  9. Modified: E. Tick
  10. Date:     January 12 1989
  11.  
  12. Notes:
  13. 1. To run:
  14.     ?- go(T,N).
  15. where T is time and N should be output 313.
  16.  
  17. 2. This version includes the generators in the answer (KL1 version doesn't)
  18.  
  19. 3. This version has tuple length hardwired: BE CAREFUL!
  20.  
  21. 4. Here we use a psuedo-hash 2--3 tree: each tuple has a hash key as its first
  22. element, thus we do not need to implement buckets: the 2--3 tree code takes
  23. care of synonyms by continuing to check the rest of the tuple!  Note that
  24. the hash function is very good: only five synonyms generated out of 313 keys.
  25. -----------------------------------------------------------------------------
  26. :- sequential.
  27. :- parallel member/2, umember/2.
  28. */
  29.  
  30. go(T,N) :-
  31.     init_sos(Kernel,Sub),
  32.     time(_),
  33.     loop(Kernel, Sub, Kernel, Hbg, Kernel),
  34.     time(T),
  35.     count(Hbg, N).
  36.  
  37. init_sos(Sos,Sub) :-
  38.     sos(Sos),
  39.     extend_tree(Sos,nil,Sub).
  40.  
  41. % Sos = list of tuples that need to be processed
  42. % Sub = tree corresponding to the (partial) semigroup Hbg
  43. % Hbg = partial semigroup tuples (initially [])
  44. loop([], _, Hbg, Hbg, _) :- !.
  45. loop(Sos, Sub, Hbg, F, Kernel) :-
  46.     findall(Tuple, newtup(Sos, Kernel, Sub, Tuple), L),
  47.     filter(L, Sub, NewSub, [], NewSos, Hbg, NewHbg),
  48.     loop(NewSos, NewSub, NewHbg, F, Kernel).
  49.  
  50. % all the parallelism comes from here...
  51. % the order of the umember goals does not seem to matter much
  52. % the first umember can be changed to member with no slow-down
  53. newtup(L,K,Sub,New) :-
  54.     umember(E1,L),     % new candidates
  55.     umember(E2,K),     % kernel (four elements here)
  56.     bigm(E2,E1,New),
  57.     \+ acc23(Sub,New).
  58.  
  59. filter(   [], Sub,  Sub, Sos,  Sos, Hbg,  Hbg).
  60. filter([H|T], Sub, SubF, Sos, SosF, Hbg, HbgF) :-
  61.     (add23(Sub,H,Sub1) ->
  62.         Sos1=[H|Sos], 
  63.         Hbg1=[H|Hbg]
  64.     ;
  65.         Sub1=Sub, 
  66.         Sos1=Sos,
  67.         Hbg1=Hbg
  68.     ),
  69.     filter(T, Sub1, SubF, Sos1, SosF, Hbg1, HbgF).
  70.  
  71. bigm(W1,W2,P) :- 
  72.     functor(P,tuple,41),           % one extra element for hash key...
  73.     mtab(Table),
  74.     bigm(2,W1,W2,P,Table,0).
  75.  
  76. bigm(42,_,_,P,_,Key) :- !,         % insert hash key as first element!
  77.     arg(1,P,Key).
  78. bigm(I,W0,W1,P,Table,Key) :- I<42,
  79.     arg(I,W0,X),
  80.     arg(I,W1,Y),
  81.     arg(X,Table,Row), 
  82.     arg(Y,Row,Z),
  83.     arg(I,P,Z),
  84.     J is I+1,
  85.     NewKey is Z+Key*3,             % hash function overflows, but gets only
  86.     bigm(J,W0,W1,P,Table,NewKey).  % five synonyms in 313 tuples!
  87.  
  88. % utilities...
  89. lmember(H,[H|_]). 
  90. lmember(H,[_|T]) :- lmember(H,T).
  91.  
  92. % unrolling pass this point doesn't improve things...
  93.  
  94. umember(H,[H|_]).
  95. umember(H,[_,H|T]).
  96. umember(H,[_,_,H|T]).
  97. umember(H,[_,_,_,H|T]).
  98. umember(H,[_,_,_,_|T]) :- umember(H,T).
  99.  
  100. extend_tree([],S,S).
  101. extend_tree([E|T],S,S1) :-
  102.     add23(S,E,S2),
  103.     extend_tree(T,S2,S1).
  104.  
  105. count(L,N) :- count(L,0,N).
  106. count([X|Xs],M,N) :- M1 is M+1, count(Xs,M1,N).
  107. count([],N,N).
  108.  
  109. time(T) :- statistics(runtime,[_,T]).
  110.  
  111. % 2-3 Trees: code from I. Bratko, "Prolog Programming for AI"
  112. acc23(l(X),           X) :-          !.
  113. acc23(n2(T1,M,_),     X) :-  M @> X, !, acc23(T1,X).
  114. acc23(n2(_,_,T2),     X) :-          !, acc23(T2,X).
  115. acc23(n3(T1,M2,_,_,_),X) :- M2 @> X, !, acc23(T1,X).
  116. acc23(n3(_,_,T2,M3,_),X) :- M3 @> X, !, acc23(T2,X).
  117. acc23(n3(_,_,_,_,T3), X) :-             acc23(T3,X).
  118.  
  119. add23(Tree,X,Tree1) :- 
  120.     ins(Tree,X,Tree1).
  121. add23(Tree,X,n2(T1,M2,T2)) :- 
  122.     ins(Tree,X,T1,M2,T2).
  123.  
  124. ins(nil,X,l(X)) :- !.
  125. ins(n2(T1,M,T2),X,n2(NT1,M,T2)) :- M @> X,
  126.     ins(T1,X,NT1).
  127. ins(n2(T1,M,T2),X,n3(NT1a,Mb,NT1b,M,T2)) :- M @> X, !,
  128.     ins(T1,X,NT1a,Mb,NT1b).
  129. ins(n2(T1,M,T2),X,n2(T1,M,NT2)) :- X @> M, 
  130.     ins(T2,X,NT2).
  131. ins(n2(T1,M,T2),X,n3(T1,M,NT2a,Mb,NT2b)) :- X @> M, !,
  132.     ins(T2,X,NT2a,Mb,NT2b).
  133. ins(n3(T1,M2,T2,M3,T3),X,n3(NT1,M2,T2,M3,T3)) :- M2 @> X, !,
  134.     ins(T1,X,NT1).
  135. ins(n3(T1,M2,T2,M3,T3),X,n3(T1,M2,NT2,M3,T3)) :- X @> M2, M3 @> X, !,
  136.     ins(T2,X,NT2).
  137. ins(n3(T1,M2,T2,M3,T3),X,n3(T1,M2,T2,M3,NT3)) :- X @> M3,
  138.     ins(T3,X,NT3).
  139.  
  140. ins(l(A),X,l(A),X,l(X)) :- X @> A, !.
  141. ins(l(A),X,l(X),A,l(A)) :- A @> X, !.
  142. ins(n3(T1,M2,T2,M3,T3),X,n2(NT1a,Mb,NT1b),M2,n2(T2,M3,T3)) :- M2 @> X, !,
  143.     ins(T1,X,NT1a,Mb,NT1b).
  144. ins(n3(T1,M2,T2,M3,T3),X,n2(T1,M2,NT2a),Mb,n2(NT2b,M3,T3)) :- 
  145.     X @> M2, M3 @> X, !,
  146.     ins(T2,X,NT2a,Mb,NT2b).
  147. ins(n3(T1,M2,T2,M3,T3),X,n2(T1,M2,T2),M3,n2(NT3a,Mb,NT3b)) :- X @> M3,
  148.     ins(T3,X,NT3a,Mb,NT3b).
  149.  
  150. /*
  151. % show tree...
  152. show(T) :- show(T,0).
  153.  
  154. show(nil, _).
  155. show(l(A),H) :- tab(H), write(A), nl.
  156. show(n2(T1,M,T2),H) :-
  157.     H1 is H+5,
  158.     show(T2,H1),
  159.     tab(H), write('--'), nl,
  160.     tab(H), write(M), nl,
  161.     tab(H), write('--'), nl,
  162.     show(T1,H1).
  163. show(n3(T1,M2,T2,M3,T3),H) :-
  164.     H1 is H+5,
  165.     show(T3,H1),
  166.     tab(H), write('--'), nl,
  167.     tab(H), write(M3), nl,
  168.     show(T2,H1),
  169.     tab(H), write(M2), nl,
  170.     tab(H), write('--'), nl,
  171.     show(T1,H1).
  172. */
  173.  
  174. /* 
  175. % original problem (Melbourne paper by Overbeek & Lusk)
  176. sos([tuple(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5),
  177.      tuple(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
  178.      tuple(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,5,5,5,5,5,4,4,4,4,4),
  179.      tuple(1,2,3,5,4,1,2,3,5,4,1,2,3,5,4,1,2,3,5,4,1,2,3,5,4)]).
  180. */
  181.  
  182. % 309+4 solutions: 
  183. % to boost execution time by 20% switch elements 28 & 29 in last row!
  184. sos([tuple(1000, 1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4, 
  185.            5,5,5,5,5,3,3,3,3,3,5,5,5,5,5,4,4,4,4,4),
  186.      tuple(2000, 1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5, 
  187.            1,2,3,4,5,1,2,3,4,5,1,3,2,4,5,1,2,3,4,5),
  188.      tuple(3000, 1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,5,5,5,5,5,
  189.            4,4,4,4,4,2,2,2,2,2,4,4,4,4,4,3,3,3,3,3),
  190.      tuple(4000, 1,2,3,5,4,1,2,3,5,4,1,2,3,5,4,1,2,3,5,4, 
  191.            1,2,3,5,4,1,2,3,4,5,1,2,3,5,4,1,2,3,5,4)]).
  192.  
  193. mtab(table(row(1,1,1,1,1),
  194.            row(1,2,1,4,1),
  195.            row(1,1,3,1,5),
  196.            row(1,1,4,1,2),
  197.            row(1,5,1,3,1))).
  198.  
  199.